﻿using InstallationClient.Hubs;
using Microsoft.AspNetCore.SignalR;
using MQTTnet;
using MQTTnet.Server;
using System.Data.SqlClient;

namespace InstallationClient.Mqtt {
    public class MqttServerHelper {

        private readonly IHubContext<LogHub> _hubContext;

        private MqttServer _mqttServer;
        /// <summary>
        /// 构造函数
        /// </summary>
        public MqttServerHelper(IHubContext<LogHub> hubContext) {
            _hubContext = hubContext;

            var options = new MqttServerOptionsBuilder()
                 .WithDefaultEndpoint()
                 .WithDefaultEndpointPort(1883)
                 .Build();

            var factory = new MqttFactory();
            _mqttServer = factory.CreateMqttServer(options);

            _mqttServer.ClientConnectedAsync += MqttServerClientConnectedHandlerDelegate;

            _mqttServer.ClientDisconnectedAsync += MqttServerClientDisconnectedHandlerDelegate;

            _mqttServer.ApplicationMessageEnqueuedOrDroppedAsync += MqttServerClientMessageReceived;

            _mqttServer.ApplicationMessageNotConsumedAsync += MqttServerClientMessageReceived;
            _mqttServer.LoadingRetainedMessageAsync += MqttServerClientMessageReceived;
        }
        /// <summary>
        /// 启动MQTT服务器
        /// </summary>
        /// <returns></returns>
        public async Task RunMqttServer() {
            await _mqttServer.StartAsync();
        }

        /// <summary>
        /// 客户端连接事件处理
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task MqttServerClientConnectedHandlerDelegate(ClientConnectedEventArgs args) {

            await _hubContext.Clients.All.SendAsync("ReceiveData", $"客户端:{args.ClientId} 已经连接!!");
            await Task.CompletedTask;

        }
        /// <summary>
        /// 客户端断开连接事件处理
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task MqttServerClientDisconnectedHandlerDelegate(ClientDisconnectedEventArgs args) {

            await _hubContext.Clients.All.SendAsync("ReceiveData", $"客户端:{args.ClientId}  已经断开连接!!");
            await Task.CompletedTask;

        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task MqttServerClientMessageReceived(ApplicationMessageEnqueuedEventArgs args) {
            var data = args.ApplicationMessage.PayloadSegment;
            var str = System.Text.Encoding.UTF8.GetString(data);
            await _hubContext.Clients.All.SendAsync("ReceiveData", $"接受指令:{str} !!");

            await Task.CompletedTask;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task MqttServerClientMessageReceived(ApplicationMessageNotConsumedEventArgs args) {
            var data = args.ApplicationMessage.PayloadSegment;
            string message = System.Text.Encoding.UTF8.GetString(data);
            if (args.ApplicationMessage.Topic == "topic_databasebackup") {
                var res = Enum.TryParse(message, out MqttDirective directive);
                if (res) {
                    switch (directive) {
                        case MqttDirective.BaackupMSSQL:
                            message = $"接收到指令:备份SQLServer数据库!!";
                            await BaackupMSSQL();
                            break;
                        default:
                            message = $"接受指令:{message} !!";
                            break;
                    }
                } else {
                    message = $"指令:{message} 无效 !!";
                }
            }
            await _hubContext.Clients.All.SendAsync("ReceiveData", message);
            await Task.CompletedTask;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task MqttServerClientMessageReceived(LoadingRetainedMessagesEventArgs args) {


            await Task.CompletedTask;

        }

        /// <summary>
        /// 备份SQLServer数据库
        /// </summary>
        private async Task<bool> BaackupMSSQL() {

            //error = "";
            //var dbConn = $"Data Source={model.ServerAddress};Initial Catalog={model.DataBase};User ID={model.UserName};Password={model.Password};";
            //SqlConnection connection = new SqlConnection(dbConn);
            //try {
            //    connection.Open();

            //    SqlCommand command = new SqlCommand();
            //    command.Connection = connection;
            //    string backupSql = $"backup database {model.DataBase} to disk = '{fileName}'";
            //    //// 排除指定的表数据
            //    //var arr = model.Task.ExcludedTables.IsNullOrEmpty() ? new List<string>() : model.Task.ExcludedTables.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
            //    //foreach (string tableName in arr) {
            //    //    backupSql += $" EXCLUDE TABLE {tableName}";
            //    //}
            //    command.CommandText = backupSql;
            //    command.CommandTimeout = 300;
            //    command.ExecuteNonQuery();
            //    return true;
            //} catch (Exception ex) {
            //    error = ex.Message.ToString();
            //    return false;
            //} finally {
            //    connection.Close();
            //    connection.Dispose();
            //}
            await Task.CompletedTask;
            return true;
        }
    }
}
